home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
star-1_0.tar
/
forms.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-22
|
4KB
|
200 lines
/* forms.c -- STAR Formats
This file is part of STAR, the Saturn Macro Assembler.
STAR is not distributed by the Free Software Foundation. Do not ask
them for a copy or how to obtain new releases. Instead, send e-mail to
the address below. STAR is merely covered by the GNU General Public
License.
Please send your comments, ideas, and bug reports to
Jan Brittenson <bson@ai.mit.edu>
*/
/* Copyright (C) 1990, 1991 Jan Brittenson.
STAR is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
STAR is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with STAR; see the file COPYING. If not, to obtain a copy, write
to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
USA, or send e-mail to bson@ai.mit.edu. */
#include <stdio.h>
#include "star.h"
#include "code.h"
/* Global variables */
extern errcnt, pass;
/* Local data */
char *mnam[] = {
"*UNDEFINED*",
"register",
"immediate",
"register indirect",
"ID",
"C nibble",
"P+1"};
/* Return name of addressing mode */
static char *modename(argp)
register struct astruct *argp;
{
register int type;
type = argp->type;
/* Illegal mode? */
if(type < T_REG || type > T_ID)
return(mnam[0]);
return(mnam[type]);
}
/* Make sure disp1 field is in selected range.
* The range should contain 0.
*/
void assert_imm_range(argp, lolimit, hilimit)
struct astruct *argp;
INT lolimit;
unsigned INT hilimit;
{
/* Implicit isimm() */
if(argp->type != T_IMM)
{
/* Display message */
isimm(argp);
argp->disp1 = lolimit;
return;
}
/* Test range */
if(hilimit && lolimit &&
((argp->disp1 > 0 && (unsigned INT) argp->disp1 > hilimit) ||
(argp->disp1 < 0 && (INT) argp->disp1 < lolimit)))
{
/* Out of range -- signal error and set value to 0 */
sgnerr("Argument value of 0x%lx out of range", /* 0x%lx to 0x%lx", */
(long) argp->disp1 /* , (long) lolimit, (long) hilimit */ );
argp->disp1 = 0;
}
}
/* Make sure INT is in selected range */
void assert_range(i, lolimit, hilimit)
INT i, lolimit;
unsigned INT hilimit;
{
struct astruct a;
a.type = T_IMM;
a.disp1 = i;
assert_imm_range(&a, lolimit, hilimit);
}
/* Make sure argument is of mode register
* If not, make it A and signal error
*/
isanyreg(argp)
register struct astruct *argp;
{
if(argp->type == T_REG)
return(TRUE);
sgnerr("Must be register, not %s", modename(argp));
argp->type = T_REG;
argp->pres = 0;
argp->reg = 0;
return(FALSE);
}
/* Make sure argument is of mode immediate
* If not, make it #0 and signal error
*/
isimm(argp)
register struct astruct *argp;
{
if(argp->type == T_IMM)
return(TRUE);
sgnerr("Must be value, not %s", modename(argp));
/* Make it #0 */
argp->type = T_IMM;
argp->disp1= 0;
argp->pres = 0;
return(FALSE);
}
/* Generate jump offset */
gendisp(disp, dispdiff, op3, op4)
long disp;
int dispdiff, op3, op4;
{
register int qsav;
/* Check maximum range */
if((disp < -(long) 0x8000 || disp > (long) 0x7fff))
{
sgnwrn("Displacement of %lx out of 16-bit range", disp);
disp = 0L;
}
/* Will it fit in 3 nibbles? */
if(disp >= -0x800 && disp <= 0x7ff)
{
/* Sure, output opcode and offset */
code1(op3);
code3(disp);
return;
}
/* No, use four nibbles */
disp += dispdiff;
code2(op4);
code4(disp);
}
/* Reverse bits in byte */
revbits(mask)
unsigned int mask;
{
static unsigned int i;
register unsigned int mask1,mask2;
for(mask1 = mask, i = mask2 = 0; i<8; i++)
{
mask2 <<= 1;
mask2 |= (mask1 & 1);
mask1 >>= 1;
}
return(mask2);
}